package com.gframework.util;

import org.apache.commons.lang3.StringUtils;
import org.springframework.lang.Nullable;

/**
 * 字符串工具栏扩展.
 * <p>本类是基于apache lang3中的StringUtils进行方法的扩展，并保持着线程安全、不可变、null安全的处理模式。
 * <ul>
 * <li><strong>repeat {@code -} </strong>创建n个指定字符</li>
 * <li><strong>leftPad/rightPad {@code -} </strong>左对齐/右对齐，并补全字符</li>
 * <li><strong>join {@code -} </strong>数组使用指定分隔符拼接</li>
 * <li><strong>toMapUnderscore/toCamelCase {@code -} </strong>数据库命名规范和驼峰命名规范互相转换</li>
 * </ul>
 * 
 * @since 2.0.0
 * @author Ghwolf
 *
 */
public class GStringUtils extends StringUtils{
	private GStringUtils(){
	}
	
	/**
	 * 将一个对象安全的转换为字符串.<br>
	 * 和String.valueOf不同的是，如果值为null，则返回null而不是返回字符串"null"
	 * @param o 要转换的对象
	 * @return 返回转换后的字符串
	 */
	@Nullable
	public static String toString(@Nullable Object o) {
		return o == null ? null : o.toString();
	}
	
	/**
	 * 将一个字符串转换为数据库所习惯的命名规则的字符串(转大写).<br>
	 * 例如：userList {@code ->} USER_LIST<br>
	 * ABC {@code ->} A_B_C
	 * 
	 * @param str 要转换的字符串，如果为null，则不做任何事情
	 * @return 返回转换后的字符串
	 */
	@Nullable
	public static String toMapUnderscore(@Nullable String str) {
		if (str == null || str.length() == 0) {
			return str;
		}
		StringBuilder sb = new StringBuilder(str.length() + 8);
		sb.append(Character.toUpperCase(str.charAt(0)));
		final int length = str.length();
		for (int x = 1 ; x < length ; x ++) {
			char c = str.charAt(x);
			if (c >= 'A' && c <= 'Z' && x != 0) {
				sb.append('_');
			}
			sb.append(Character.toUpperCase(c));
		}
		return sb.toString();
	}

	/**
	 * 将一个字符串转换为驼峰命名法的字符串(首字母小写).<br>
	 * 例如：
	 * <ul>
	 * <li>User_list {@code ->} userList</li>
	 * <li>A_BS_C {@code ->} aBsC</li>
	 * <li>__user___hello_ {@code ->} userHello</li>
	 * </ul>
	 * @param str 要转换的字符串，如果为null，则不做任何事情
	 * @return 返回转换后的字符串
	 */
	@Nullable
	public static String toCamelCase(@Nullable String str) {
		if (str == null || str.length() == 0) {
			return str;
		}
		str = StringUtils.strip(str, "_");
		StringBuilder sb = new StringBuilder(str.length());
		final int length = str.length();
		char lastChar = '_';
		for (int x = 0 ; x < length ; x ++) {
			char c = str.charAt(x);
			if (c != '_') {
				if (lastChar == '_' && sb.length() != 0) {
					sb.append(Character.toUpperCase(c));
				} else {
					sb.append(Character.toLowerCase(c));
				}
			}
			lastChar = c ;
		}
		return sb.toString();
	}
	
}
